﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using AdvEvaluator;
using AdvEvaluator.Command;

namespace AdvEditor
{
    /// <summary>
    /// AdvEditorのフォーム
    /// </summary>
    public partial class MainForm : Form
    {
        private ProjectData projectData;
        private string projectPath;

        /// <summary>
        /// 初期化
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
            projectData = null;
        }


        #region メニューバー・ツールバーのイベントハンドラ
        /// <summary>
        /// 「終了」を選択したときの処理
        /// </summary>
        private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        /// <summary>
        /// 「新しいプロジェクト」を選択したときの処理
        /// </summary>
        private void toolStripMenuItem_NewProject_Click(object sender, EventArgs e)
        {
            // 新規プロジェクト作成ダイアログを開く
            using (NewProjectDialog d = new NewProjectDialog()) {
                if (d.ShowDialog(this) == DialogResult.OK) {
                    CreateProject(d.BasePath, d.ProjectName, d.GameTitle);
                }
            }
        }
        /// <summary>
        /// 「プロジェクトを開く」を選択したときの処理
        /// </summary>
        private void toolStripMenuItem_OpenProject_Click(object sender, EventArgs e)
        {
            // フォルダ選択ダイアログを開く
            if (folderBrowserDialog_Project.ShowDialog(this) == DialogResult.OK) {
                // プロジェクトを開く
                OpenProject(folderBrowserDialog_Project.SelectedPath);
            }
        }
        #endregion


        #region プロジェクト新規作成
        /// <summary>
        /// プロジェクトを新規作成する
        /// </summary>
        /// <param name="basePath"></param>
        /// <param name="projectName"></param>
        /// <param name="gameTitle"></param>
        private void CreateProject(string basePath, string projectName, string gameTitle)
        {
            // プロジェクトのフォルダのパス
            projectPath = Path.Combine(basePath, projectName) + Path.DirectorySeparatorChar;
            // プロジェクトのフォルダを作成
            CreateProjectDirectory(projectPath);
            // プロジェクトデータを作成し、ファイルに書き込む
            projectData = new ProjectData { Name = projectName, GameTitle = gameTitle };
            projectData.Save(Path.Combine(projectPath, projectName+".advproj"));
            // 初期シナリオを作成
            CreateScenarioFile(projectData.InitialScenario);
            // AdvEvaluatorの実行ファイルをコピー
            CopyExecutableFiles();
        }
        /// <summary>
        /// 引数で与えた位置にプロジェクトを格納するディレクトリを用意する
        /// </summary>
        /// <param name="path"></param>
        private void CreateProjectDirectory(string path)
        {
            // すでに存在するならいったん削除する
            if (Directory.Exists(path)) {
                Directory.Delete(path, true);
            }
            char s = Path.DirectorySeparatorChar;
            Directory.CreateDirectory(path);
            Directory.CreateDirectory(Path.Combine(path, "シナリオ"));
            Directory.CreateDirectory(Path.Combine(path, "画像"+s+"立ち絵"));
            Directory.CreateDirectory(Path.Combine(path, "画像"+s+"背景"));
            Directory.CreateDirectory(Path.Combine(path, "画像"+s+"ボタン"));
            Directory.CreateDirectory(Path.Combine(path, "サウンド"+s+"BGM"));
            Directory.CreateDirectory(Path.Combine(path, "サウンド"+s+"SE"));
        }
        /// <summary>
        /// 新しいシナリオデータを projectPath/シナリオ に作成する。シナリオフォルダ内に作成される。
        /// </summary>
        /// <param name="fileName">ファイル名</param>
        private void CreateScenarioFile(string fileName)
        {
            // 初期データをXMLに書き込む
            string path = Path.Combine(Path.Combine(projectPath, "シナリオ"), fileName);
            using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) {
                System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(CommandParams[]));
                serializer.Serialize(fs, new CommandParams[0]);
            }
        }
        /// <summary>
        /// AdvEvaluatorのバイナリをプロジェクトフォルダにコピー
        /// </summary>
        private void CopyExecutableFiles()
        {           
            File.Copy(
                string.Format("{0}AdvEvaluator.exe", AppDomain.CurrentDomain.BaseDirectory),
                string.Format("{0}{1}.exe", projectPath, projectData.Name)
            );
            File.Copy(
                string.Format("{0}Yanesdk.dll", AppDomain.CurrentDomain.BaseDirectory),
                string.Format("{0}Yanesdk.dll", projectPath)
            );
            Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(
                string.Format("{0}lib", AppDomain.CurrentDomain.BaseDirectory),
                string.Format("{0}lib", projectPath),
                Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs
            );
            File.SetAttributes(string.Format("{0}Yanesdk.dll", projectPath), FileAttributes.Hidden);
            File.SetAttributes(string.Format("{0}lib", projectPath), FileAttributes.Hidden);
            using (FileStream fs = new FileStream(string.Format("{0}{1}.exe", projectPath, projectData.Name), FileMode.Open, FileAccess.ReadWrite)) {
                fs.Position = fs.Length - 1;
                fs.Write(projectData.RijndaelKey, 0, projectData.RijndaelKey.Length);
            }
            File.SetAttributes(string.Format("{0}{1}.exe", projectPath, projectData.Name), FileAttributes.ReadOnly | FileAttributes.Encrypted);
        }
        #endregion


        #region プロジェクトを開く
        /// <summary>
        /// 引数で与えられたディレクトリにあるプロジェクトを開き、各コントロールに内容を表示する
        /// </summary>
        /// <param name="projectPath"></param>
        private void OpenProject(string projectPath)
        {
            if (!IsProjectDirectory(projectPath)) {
                MessageBox.Show("AdvCreatorのプロジェクトではありません。", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }
        /// <summary>
        /// 指定したディレクトリがAdvCreatorのプロジェクトのものであるかどうか
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private bool IsProjectDirectory(string path)
        {
            return Directory.GetFiles(path, "*.advproj", SearchOption.TopDirectoryOnly).Length > 0;
        }
        /// <summary>
        /// コントロールの有効状態を切り替える
        /// </summary>
        /// <param name="b"></param>
        private void SwitchControlsEnabled(bool b)
        {

        }
        #endregion

    }
}
